/**
 * visit服务实现
 *
 * @author sxf
 * @email sxf02615@163.com
 * @date 2025/1/15
 */
package com.sxf.crm.service.impl;


import com.sxf.crm.dto.VisitDTO;
import com.sxf.crm.entity.Customer;
import com.sxf.crm.entity.User;
import com.sxf.crm.entity.Visit;
import com.sxf.crm.entity.VisitCollaborator;
import com.sxf.crm.enums.VisitStatus;
import com.sxf.crm.enums.VisitType;
import com.sxf.crm.repository.CustomerRepository;
import com.sxf.crm.repository.VisitCollaboratorRepository;
import com.sxf.crm.repository.VisitRepository;
import com.sxf.crm.service.UserService;
import com.sxf.crm.service.VisitService;

import lombok.RequiredArgsConstructor;

import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 拜访服务实现类
 *
 * @author sxf
 * @email sxf02615@163.com
 * @date 2025/6/1
 */
@Service
@RequiredArgsConstructor
public class VisitServiceImpl implements VisitService {

    private final VisitRepository visitRepository;

    private final CustomerRepository customerRepository;

    private final VisitCollaboratorRepository visitCollaboratorRepository;

    private final UserService userService;

    @Override
    @Transactional
    public Visit createVisit(Visit visit, Long customerId, List<Long> collaboratorIds) {
        // 设置客户
        Customer customer = customerRepository.findById(customerId)
                .orElseThrow(() -> new RuntimeException("客户不存在"));
        visit.setCustomer(customer);

        // 保存拜访
        Visit savedVisit = visitRepository.save(visit);

        // 设置协同人
        if (collaboratorIds != null && !collaboratorIds.isEmpty()) {
            List<VisitCollaborator> collaborators = collaboratorIds.stream()
                    .map(id -> {
                        User user = userService.getUserById(id);
                        VisitCollaborator collaborator = new VisitCollaborator();
                        collaborator.setVisit(savedVisit);
                        collaborator.setUser(user);
                        return collaborator;
                    })
                    .collect(Collectors.toList());
            visitCollaboratorRepository.saveAll(collaborators);
        }

        return savedVisit;
    }

    @Override
    @Transactional
    public VisitDTO updateVisit(Visit visit, Long customerId, List<Long> collaboratorIds) {
        Visit existingVisit = visitRepository.findById(visit.getId())
                .orElseThrow(() -> new RuntimeException("拜访记录不存在"));

        // 更新基本信息
        existingVisit.setTitle(visit.getTitle());
        existingVisit.setContent(visit.getContent());
        existingVisit.setVisitTime(visit.getVisitTime());
        existingVisit.setVisitType(visit.getVisitType());
        existingVisit.setVisitResult(visit.getVisitResult());
        existingVisit.setNextPlan(visit.getNextPlan());
        existingVisit.setVisitAddress(visit.getVisitAddress());
        existingVisit.setVisitPurpose(visit.getVisitPurpose());

        // 更新客户关系
        if (customerId != null) {
            Customer customer = customerRepository.findById(customerId)
                    .orElseThrow(() -> new RuntimeException("客户不存在"));
            existingVisit.setCustomer(customer);
        }

        // 更新协同人关系
        if (collaboratorIds != null) {
            // 删除旧的协同人关系
            visitCollaboratorRepository.deleteByVisitId(existingVisit.getId());
            
            // 添加新的协同人关系
            if (!collaboratorIds.isEmpty()) {
                List<VisitCollaborator> collaborators = collaboratorIds.stream()
                        .map(id -> {
                            User user = userService.getUserById(id);
                            VisitCollaborator collaborator = new VisitCollaborator();
                            collaborator.setVisit(existingVisit);
                            collaborator.setUser(user);
                            return collaborator;
                        })
                        .collect(Collectors.toList());
                visitCollaboratorRepository.saveAll(collaborators);
            }
        }

        Visit updatedVisit = visitRepository.save(existingVisit);
        return convertToDTO(updatedVisit);
    }

    @Override
    @Transactional
    public void deleteVisit(Long id) {
        // 删除协同人关系
        visitCollaboratorRepository.deleteByVisitId(id);
        // 删除拜访
        visitRepository.deleteById(id);
    }

    @Override
    @Transactional(readOnly = true)
    public VisitDTO getVisit(Long id) {
        Visit visit = visitRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("拜访不存在"));
        return convertToDTO(visit);
    }

    @Override
    @Transactional(readOnly = true)
    public List<VisitDTO> getVisitsByUser(Long userId) {
        List<Visit> visits = visitRepository.findByUserId(userId);
        return visits.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public List<VisitDTO> getVisitsByCustomer(Long customerId) {
        List<Visit> visits = visitRepository.findByCustomerId(customerId);
        return visits.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public Page<VisitDTO> getVisitsByPage(String title, String visitType, String visitStatus,
                                        Long userId, Long customerId, Pageable pageable) {
        // 转换枚举类型
        VisitType type = visitType != null ? VisitType.valueOf(visitType) : null;
        VisitStatus status = visitStatus != null ? VisitStatus.valueOf(visitStatus) : null;
        
        Page<Visit> visits = visitRepository.findByConditions(title, type, status,
                userId, customerId, pageable);
        return visits.map(this::convertToDTO);
    }

    @Override
    @Transactional
    public VisitDTO updateVisitStatus(Long id, String newStatus) {
        Visit visit = visitRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("拜访不存在"));
        
        // 检查状态修改规则：计划中 -> 已完成/已取消，已完成/已取消不能再修改
        String currentStatus = visit.getVisitStatus();
        
        if (currentStatus == VisitStatus.COMPLETED.name() || currentStatus == VisitStatus.CANCELLED.name()) {
            throw new RuntimeException("已完成或已取消的拜访状态不能再修改");
        }
        
        if (currentStatus == VisitStatus.PLANNED.name() && 
            (newStatus != VisitStatus.COMPLETED.name() && newStatus != VisitStatus.CANCELLED.name())) {
            throw new RuntimeException("计划中的拜访只能修改为已完成或已取消状态");
        }
        
        visit.setVisitStatus(newStatus);
        Visit updatedVisit = visitRepository.save(visit);
        return convertToDTO(updatedVisit);
    }

    @Override
    @Transactional(readOnly = true)
    public VisitDTO getVisitDetail(Long id) {
        Visit visit = visitRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("拜访不存在"));
        return convertToDTO(visit);
    }

    private VisitDTO convertToDTO(Visit visit) {
        VisitDTO dto = new VisitDTO();
        BeanUtils.copyProperties(visit, dto);
        
        
        // 设置客户信息
        if (visit.getCustomer() != null) {
            dto.setCustomerId(visit.getCustomer().getId());
            dto.setCustomerName(visit.getCustomer().getName());
        }
        
        // 设置拜访人信息
        if (visit.getUser() != null) {
            dto.setUserId(visit.getUser().getId());
            dto.setUserName(visit.getUser().getUsername());
        }
        if(visit.getVisitStatus()!=null){
            dto.setVisitStatus(visit.getVisitStatus());
            dto.setVisitStatusName(VisitStatus.valueOf(visit.getVisitStatus()).getDescription());
        }
        if(visit.getVisitType()!=null){
            dto.setVisitType(visit.getVisitType());
            dto.setVisitTypeName(VisitType.valueOf(visit.getVisitType()).getDescription());
        }
        // 设置协同人信息
        List<VisitCollaborator> collaborators = visitCollaboratorRepository.findByVisitId(visit.getId());
        dto.setCollaboratorIds(collaborators.stream()
                .map(c -> c.getUser().getId())
                .collect(Collectors.toList()));
        dto.setCollaboratorNames(collaborators.stream()
                .map(c -> c.getUser().getUsername())
                .collect(Collectors.toList()));
        
        return dto;
    }
}
